<?php


namespace App\Http\Api\Controllers;


use App\Library\JsonData;
use App\Models\CoCargo;
use App\Models\CoDistribution;
use App\Models\CoDistributionType;
use App\Models\CoExpress;
use App\Models\CoOrder;
use App\Models\CoOrderComments;
use App\Models\CoOrderExpress;
use App\Models\CoSchool;
use App\Models\CoSchoolBuilding;
use App\Models\CoUserAddress;
use App\Models\CoUserCity;
use App\Models\CoWeight;
use Godruoyi\Snowflake\Snowflake;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Yansongda\LaravelPay\Facades\Pay;
use function App\common\result;

class OrderController extends Controller
{
    protected $error;
    public function __construct(Request $request)
    {
        // 调用父类前置方法
        parent::__construct();
        $this->api_token = trim($request->header('token'));
        $this->get_user();
        if(empty($this->user_info)){
            return JsonData::error('未登录','',601);
        }
        if($this->user_info->type !=1){
            return JsonData::error('用户禁止登录','',601);
        }
    }

    /**
     * 订单价格计算
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
   public function order_ore(Request $request){
       try {
           $validator = Validator::make($request->all(), [
               'distribution_type' => 'required|in:1,2',
               'distribution_time'=>'required',
               'school_id'=>'required|integer',
               'order_type'=>'required|in:1,2',
               'city_id'=>'required|integer',
               'data'=>'required',
           ]);
           if ($validator->fails()) {
               return JsonData::error('参数错误','',500);
           }
           //赋值
           $distribution_type=$request->distribution_type;// 是否上楼 1上 2否
           $distribution_time = $request->distribution_time;
           $school_id=$request->school_id;
           $order_type=$request->order_type;
           $city_id=$request->city_id;
           $data=$request->data;
           if(!empty($data)){
               $data = json_decode($data,true);
               if(empty($data)){
                   return JsonData::error( "快递信息不全",'',500);
               }
           }
           //查询

           $CoOrder = new CoOrder();
           $CoOrder->city_id = $city_id;
           $school_info=CoSchool::where("id",$school_id)->where('status',1)->first();
           if(empty($school_info)){
               return JsonData::error('学校不存在','',500);
           }

           $CoOrder->school_id = $school_id;
           //获取地址信息
           $city = $this->get_city($city_id);
           if(empty($city)){
               return JsonData::error('地址不存在',$city,500);
           }
           //订单价格
           //根据地址获取楼栋配送价格
           $school_building = CoSchoolBuilding::where('id',$city->school_building_id)->first();
           if(empty($school_building)){
               return JsonData::error('配送楼栋不存在',$city,500);
           }
           $CoOrder->price =0;
           if($distribution_type == 1){
               $CoOrder->price = $school_building->up_floor_Price;
           }else{
               $CoOrder->price = $school_building->no_floor_Price;
           }
           //查询配送方式
           $CoOrder->distribution_type = $distribution_type;
           $CoOrder->distribution_name = CoDistributionType::where('id',$distribution_type)->value('name');
           $CoOrder->distribution_time = $distribution_time;
           $CoOrder->user_id = $this->user_info->id;

           $CoOrder->order_type = $order_type;
           $res = $this->get_order_pre($data,$school_id,$order_type);
           if($res ==false){
               return JsonData::error( "订单发布失败",$this->error,500);
           }
           $CoOrder->price = $CoOrder->price +$res;
           $is_urgent = intval($request->get('is_urgent',0));
           if($is_urgent == 1 && $CoOrder->price>0){
               $CoOrder->is_urgent = 1;
               $ratio_price =0;
               //获取加急订单增加比例
               $order_ratio =intval(sys_config('order_ratio'));
               if($order_ratio >0){
                   $ratio_price = bcmul($CoOrder->price,$order_ratio/100,2);
               }
               $CoOrder->price = bcadd($CoOrder->price,$ratio_price,2);
           }
           if($CoOrder->price <=0){
               DB::rollBack();
               return JsonData::error( "订单价格异常",'',500);
           }
           return JsonData::success( "订单价格获取成功",$CoOrder->price,200);
        } catch (\Throwable $e) {
            DB::rollBack();
            return JsonData::error( $e,"",500);
        }
   }

    /**
     * 计算预计快递价格
     * @param $data
     */
    protected function get_order_pre($data,$school_id,$order_type=1){
        $price = 0;
        $list =[];
        foreach ($data as $k=>$v){
            //获取重量信息
            if(isset($v['weight_id']) && !empty($v['weight_id'])){
                $weight = $this->get_weight($school_id,$v['weight_id']);
                if(empty($weight)){
                    $this->error  = '重量错误';
                    return false;
                }else{
                    $list[$k]['weight_id'] = $v['weight_id'];
                    $list[$k]['weight_name'] =$weight['name'];
                    $price = $price+$weight['price'];
                }
            }else{
                $this->error  = '重量不存在';
                return false;
            }

            //快递分类名
            if(isset($v['cargo_id']) && !empty($v['cargo_id'])){
                //获取快递类型信息
                $cargo = $this->get_cargo($v['cargo_id']);
                if(empty($cargo)){
                    $this->error  = '类型错误';
                    return false;
                }else{
                    $list[$k]['cargo_id'] = $v['cargo_id'];
                    $list[$k]['cargo_name'] = $cargo['name'];
                }
            }else{
                $this->error  = '类型不存在';
                return  false;
            }
            if($order_type == 1){
                if(isset($v['pick_method']) && !empty($v['pick_method'])){
                    $list[$k]['pick_method'] = $v['pick_method'];
                }
                if(isset($v['pick_code']) && !empty($v['pick_code'])){
                    $list[$k]['pick_code'] = $v['pick_code'];
                }else{
                    $this->error  = '取件码不存在';
                    return  false;
                }
                if(isset($v['pick_tel']) && !empty($v['pick_tel'])){
                    $list[$k]['pick_tel'] = $v['pick_tel'];
                }else{
                    $this->error  = '取件电话不存在';
                    return  false;
                }
                if(isset($v['pick_address']) && !empty($v['pick_address'])){
                    $list[$k]['pick_address'] = $v['pick_address'];
                }else{
                    $this->error  = '取件地址不存在';
                    return  false;
                }
                if(isset($v['user_note']) && !empty($v['user_note'])){
                    $list[$k]['user_note'] = $v['user_note'];
                }else{
                    $this->error  = '取件信息不存在';
                    return  false;
                }
            }else{
                if(isset($v['express_name']) && !empty($v['express_name'])){
                    $list[$k]['express_name'] = $v['express_name'];
                }else{
                    $this->error  = '快递公司信息不存在';
                    return  false;
                }
                if(isset($v['address_id']) && !empty($v['address_id'])){
                    //获取联系人信息
                    $address = $this->get_address($v['address_id']);
                    if(empty($address)){
                        $this->error  = '联系人信息不存在';
                        return false;
                    }else{
                        $list[$k]['address_id'] = $v['address_id'];
                    }
                }else{
                    $this->error  = '联系人信息不全';
                    return  false;
                }
            }

        }
        if(empty($list)){
            $this->error  = '快递信息不全';
            return false;
        }
        return $price;
    }


    /**
     * 新增订单
     * @param Request $request
     */
    public function addOrder(Request $request){
//        try {
            $validator = Validator::make($request->all(), [
                'distribution_type' => 'required|in:1,2',
                'distribution_time'=>'required',
                'school_id'=>'required|integer',
                'order_type'=>'required|in:1,2',
                'city_id'=>'required|integer',
                'data'=>'required',
            ]);
            if ($validator->fails()) {
                return JsonData::error('参数错误','',500);
            }
            //赋值
            $distribution_type=$request->distribution_type;// 是否上楼 1上 2否
            $distribution_time = $request->distribution_time;
            $school_id=$request->school_id;
            $order_type=$request->order_type;
            $is_urgent=$request->get('is_urgent',0);
            $city_id=$request->city_id;
            $data=$request->data;
            if(!empty($data)){
                $data = json_decode($data,true);
                if(empty($data)){
                    return JsonData::error( "快递信息不全",'',500);
                }
            }
            //查询

            //生成订单号
            $snow = new Snowflake();
            $order_no =  $snow->id();

            $school_info=CoSchool::where("id",$school_id)->where('status',1)->first();
            if(empty($school_info)){
                return JsonData::error('学校不存在','',500);
            }
            //获取地址信息
            $city = $this->get_city($city_id);
            if(empty($city)){
                return JsonData::error('地址不存在',$city,500);
            }

            //订单价格
            //根据地址获取楼栋配送价格
            $school_building = CoSchoolBuilding::where('id',$city->school_building_id)->first();
            if(empty($school_building)){
                return JsonData::error('配送楼栋不存在',$city,500);
            }
            $price = 0;
            if($distribution_type == 1){
                $price = $school_building->up_floor_Price;
            }else{
                $price = $school_building->no_floor_Price;
            }
            //获取楼栋价格信息
            DB::beginTransaction();
            $res = $this->get_data($data,$order_no,$school_id,$order_type);
            if($res ==false){
                DB::rollBack();
                return JsonData::error( "订单发布失败",'',500);
            }

            if(isset($res['code']) && $res['code']){
                $CoOrder = new CoOrder();
                $CoOrder->order_type = $order_type;
                $CoOrder->order_no = $order_no;
                $CoOrder->city_id = $city_id;
                $CoOrder->school_id = $school_id;
                if($city->school_building_id){
                    $CoOrder->school_building_id = $city->school_building_id;
                }
                //查询配送方式
                $CoOrder->distribution_type = $distribution_type;
                $CoOrder->distribution_name = CoDistributionType::where('id',$distribution_type)->value('name');
                $CoOrder->distribution_time = $distribution_time;
                $CoOrder->user_id = $this->user_info->id;
                //发布订单
                //计算价格
                $CoOrder->price = $price +$res['price'];
                if($is_urgent == 1 && $CoOrder->price>0){
                    $CoOrder->is_urgent = 1;
                    $ratio_price =0;
                    //获取加急订单增加比例
                    $order_ratio =intval(sys_config('order_ratio'));
                    if($order_ratio >0){
                        $ratio_price = bcmul($CoOrder->price,$order_ratio/100,2);
//                        $ratio_price = bcdiv($CoOrder->price * $order_ratio/100,100,2);
                    }
                    $CoOrder->price = bcadd($CoOrder->price,$ratio_price,2);
                }
                if($CoOrder->price <=0){
                    DB::rollBack();
                    return JsonData::error( "订单价格异常",'',500);
                }
                $user_ouder_num =0;
                //获取免单数
                $free_charge = sys_config('free_charge');
                if($free_charge >0){
                    $user_ouder_num = CoOrder::where('user_id',$this->user_info->id)->count();
                    //判断是否免单
                    if($user_ouder_num < $free_charge){
                        $CoOrder->status = 1;
                        $CoOrder->pay_status = 4;
                        $CoOrder->pay_price =0;
                        $CoOrder->pay_time = date("Y-m-d h:i:s");
                        $CoOrder->safety_code = rand_string(5,0); //生成安全码
                    }
                }
                //获取订单号
                //生成订单
                $res = $CoOrder->save();
                if($res){
                    if($user_ouder_num > $free_charge){
                        /*构造微信支付*/
                        $order = [
                            'out_trade_no' => $CoOrder->order_no,
                            'body' => '服务单-'.$CoOrder->order_no,
                            'total_fee' => $CoOrder->price * 100,
                            'openid' => $this->user_info->openid,
                        ];
                        // 验证服务器数据
                        $wechat = Pay::wechat(config("app.wechat"));
                        $result = $wechat->miniapp($order);
                        if ($result['package']) {
                            DB::commit();
                            return JsonData::success( "支付唤起成功",$result,707);
                        } else {
                            DB::rollBack();
                            return JsonData::error( "支付唤起失败",'',500);
                        }
                    }else{
                        DB::commit();
                        return JsonData::success( "订单免单",'',200);
                    }
                }else{
                    DB::rollBack();
                    return JsonData::error( "订单发布失败",'',500);
                }
            }else{
                DB::rollBack();
                return JsonData::error( "订单发布失败",'',500);
            }
//        } catch (\Throwable $e) {
//            DB::rollBack();
//            return JsonData::error( $e,"",500);
//        }
    }


    /**
     * 计算快递价格
     * @param $data
     */
    protected function get_data($data,$order_no,$school_id,$order_type=1){
        $price = 0;
        $list =[];
        foreach ($data as $k=>$v){
            $list[$k]['order_type'] = $order_type;
            $list[$k]['order_no'] = $order_no;
            //获取重量信息
            if(isset($v['weight_id']) && !empty($v['weight_id'])){
                $weight = $this->get_weight($school_id,$v['weight_id']);
                if(empty($weight)){
                    $this->error  = '重量错误';
                    return false;
                }else{
                    $list[$k]['weight_id'] = $v['weight_id'];
                    $list[$k]['weight_name'] =$weight['name'];
                    $price = $price+$weight['price'];
                }
            }else{
                $this->error  = '重量不存在';
                return false;
            }

            //快递分类名
            if(isset($v['cargo_id']) && !empty($v['cargo_id'])){
                //获取快递类型信息
                $cargo = $this->get_cargo($v['cargo_id']);
                if(empty($cargo)){
                    $this->error  = '类型错误';
                    return false;
                }else{
                    $list[$k]['cargo_id'] = $v['cargo_id'];
                    $list[$k]['cargo_name'] = $cargo['name'];
                }
            }else{
                $this->error  = '类型不存在';
                return  false;
            }

            if(isset($v['goods_name']) && !empty($v['goods_name'])){
                $list[$k]['goods_name'] = $v['goods_name'];
            }

            if($order_type == 1){
                if(isset($v['pick_method']) && !empty($v['pick_method'])){
                    $list[$k]['pick_method'] = $v['pick_method'];
                }
                if(isset($v['pick_code']) && !empty($v['pick_code'])){
                    $list[$k]['pick_code'] = $v['pick_code'];
                }else{
                    $this->error  = '取件码不存在';
                    return  false;
                }
                if(isset($v['pick_tel']) && !empty($v['pick_tel'])){
                    $list[$k]['pick_tel'] = $v['pick_tel'];
                }else{
                    $this->error  = '取件电话不存在';
                    return  false;
                }
                if(isset($v['pick_address']) && !empty($v['pick_address'])){
                    $list[$k]['pick_address'] = $v['pick_address'];
                }else{
                    $this->error  = '取件地址不存在';
                    return  false;
                }
                if(isset($v['user_note']) && !empty($v['user_note'])){
                    $list[$k]['user_note'] = $v['user_note'];
                }else{
                    $this->error  = '取件备注不存在';
                    return  false;
                }
            }else{
                if(isset($v['express_name']) && !empty($v['express_name'])){
                    $list[$k]['express_name'] = $v['express_name'];
                }else{
                    $this->error  = '快递公司不存在';
                    return  false;
                }
                if(isset($v['address_id']) && !empty($v['address_id'])){
                    //获取联系人信息
                    $address = $this->get_address($v['address_id']);
                    if(empty($address)){
                        $this->error  = '寄件地址不存在';
                        return false;
                    }else{
                        $list[$k]['address_id'] = $v['address_id'];
                    }
                }else{
                    $this->error  = '寄件地址未选则';
                    return  false;
                }
            }

        }
        if(empty($list)){
            return false;
        }
        //提交信息 发布子订单
        $CoOrderExpress = new CoOrderExpress();
        $info['code'] =  $CoOrderExpress->addAll($list);
        $info['price'] = $price;
        return $info;
    }

    /**
     * 获取价格信息
     * @param $id
     * @return mixed
     */
    protected function get_weight($school_id,$id){
        //查询重量获取价格
        $CoWeight = CoWeight::where('id',$id)->where('school_id',$school_id)->where('status',1)->first();
        if(empty($CoWeight)){{
            return false;
        }}
        return $CoWeight->toArray();
    }

    /**
     * 获取快递类型信息
     * @param $id
     * @return mixed
     */
    protected function get_cargo($id){
        //查询重量获取价格
        $CoWeight = CoCargo::where('id',$id)->where('status',1)->first();
        if(empty($CoWeight)){{
            return false;
        }}
        return $CoWeight->toArray();
    }

    /**
     * 获取联系人ID
     * @param $id
     */
    protected function get_address($id){
        //查询联系人信息
        $CoExpress = CoUserAddress::where('id',$id)->where('user_id',$this->user_info->id)->first();
        if(empty($CoExpress)){{
            return false;
        }}
        return $CoExpress->toArray();
    }

    /**
     * 查询取件或收件地址信息
     * @param $id
     */
    protected function get_city($id){
        //查询取件或收件地址信息
       return CoUserCity::where('id',$id)->where('user_id',$this->user_info->id)->first();
    }


    /**
     * 订单列表
     */
    public function orderlist(Request $request){
        try {
            $order_type = intval($request->get('order_type',1));
            if(!in_array($order_type,[1,2])){
                return JsonData::error("参数错误！",'',500);
            }
            $status = intval($request->get('status',1));
            if(!in_array($status,[1,2,3,4])){
                return JsonData::error("参数错误！",'',500);
            }
            $where['user_id'] = $this->user_info->id;
            $where['order_type'] = $order_type;
            $type =[];
            $orderBy = 'created_at';
            if($status ==1){
                $orderBy = 'pay_time';
                $type =[1];
//              $where['status'] = 1;
            }elseif ($status==2){
                $orderBy ='confirm_time';
                $type =[2,3];
//                $where['status'] =   ['in',[2,3]];
            }elseif ($status==3){
                $orderBy ='confirm_time';
                $type =[4];
//                $where['status'] =   4;
//                $where['is_comments'] =1;
            }else{
                $orderBy ='close_time';
                $type =[4];
//                $where['status'] =   4;
                $where['is_comments'] =0;
            }
            $data = CoOrder::with('usercity')
                ->with('orderexpress')
                ->with('user')
                ->where($where)
                ->orderByDesc($orderBy)
                ->whereIn('status',$type)
                ->select('id','order_no','distribution_name','distribution_time','order_type','status','pay_status','is_urgent','price','city_id','confirm_time','cancel_time','is_comments','created_at','updated_at')
                ->paginate(10);
            return JsonData::success( "返回成功",$data,200);
        }catch (\Exception $e){
            DB::rollBack();
            return JsonData::error("程序异常！",'',500);
        }
    }


    /**
     * 订单统计
     * @param Request $request
     */
    public function order_count(Request $request){
        try {
            $data['order1'] = CoOrder::where('status',1)->where('user_id',$this->user_info->id)->count();
            $data['order2'] = CoOrder::whereIn('status',[2,3])->where('user_id',$this->user_info->id)->count();
            $data['order3'] = CoOrder::where('status',4)->where('user_id',$this->user_info->id)->count();
            $data['order4'] = CoOrder::where('status',4)->where('user_id',$this->user_info->id)->where('is_comments',0)->count();
            return JsonData::success( "返回成功",$data,200);
        }catch (\Exception $e){
            DB::rollBack();
            return JsonData::error($e->getMessage(),'',500);
        }
    }

    /**
     * 订单详情
     */
    public function order_details(Request $request){
        $order_no = $request->get('order_no',0);
        if(empty($order_no)){
            return JsonData::error( "参数错误",'',500);
        }
        $data = CoOrder::with('usercity')
            ->with('user')
            ->with('orderexpress')
            ->where('user_id','=',$this->user_info->id)
            ->where('order_no','=',$order_no)->first();
        return JsonData::success( "返回成功",$data,200);
    }

    /**
     * 查看安全码
     */
    public function che_code(Request $request){
        $order_no = $request->get('order_no',0);
        if(empty($order_no)){
            return JsonData::error( "参数错误",'',500);
        }
        $data = CoOrder::where('user_id','=',$this->user_info->id)
            ->where('order_no','=',$order_no)
            ->where('status','>',0)
            ->where('pay_status','>',0)
            ->select('safety_code','status','pay_status')
            ->first();
        if(empty($data)){
            return JsonData::error( "订单无安全码",'',500);
        }else{
            return JsonData::error( "返回成功",$data,200);
        }

    }

    /**
     * 取消订单
     * @param Request $request
     */
    public function cancel_order(Request $request){
        try {
            $order_no = $request->get('order_no',0);
            if(empty($order_no)){
                return JsonData::error( "参数错误",'',500);
            }
            $data = CoOrder::where('user_id','=',$this->user_info->id)->where('order_no','=',$order_no)->first();

            if(in_array($data->status,[1,2,3])){
                DB::beginTransaction();
                if($data->status ==1 && $data->pay_status ==1){
                    //未结单可退款
                    //修改订单状态
                    $data->status=5;
                    $data->pay_status=2;
                    $data->cancel_time = date('Y-m-d H:i:s',time());
                    $res = $data->save();
                    if(!$res){
                        DB::rollBack();
                        return JsonData::error( "订单取消失败",'',500);
                    }
                    //退款操作
                    $wechat = Pay::wechat(config('app.wechat'));
                    //未结单退款
                    $order = [
                        'out_trade_no' => $data->order_no,
                        'out_refund_no' => time(),
                        'total_fee' => $data->price *100,
                        'refund_fee' => $data->price *100,
                        'refund_desc' => '服务退款-'.$data->order_no,
                        'type' => "miniapp",
                    ];
                    $result = $wechat->refund($order);
                    if($result['return_code'] =='SUCCESS'){
                        DB::commit();
                        return JsonData::success( "订单取消成功",'',200);
                    }else{
                        DB::rollBack();
                        return JsonData::error( "订单取消失败",'',500);
                    }
                }else{
                    //已接单不退款
                    //修改订单状态
                    $data->status=5;
                    $data->remarks='已接单订单不退款';
                    $data->cancel_time = date('Y-m-d H:i:s',time());
                    $res = $data->save();
                    if(!$res){
                        DB::rollBack();
                        return JsonData::error( "订单取消失败",'',500);
                    }
                    DB::commit();
                    return JsonData::success( "订单取消成功",'',200);
                }
            }else{
                return JsonData::error( "订单无法取消",'',500);
            }
        } catch (\Exception $e) {
            //配置错误时排除异常
            return JsonData::error( $e->getMessage(),'',500);
        }
    }


    /**
     * 订单评价
     * @param Request $request
     */
    public function order_comments(Request $request){
        try {
            $validator = Validator::make($request->all(), [
                "order_no"=>"required|integer",
                "text"=>"required",
                "evaluate1"=>"required|integer|max:10|min:1",
                "evaluate2"=>"required|integer|max:10|min:1",
//                "evaluate3"=>"required|integer|max:10|min:1",
            ]);
            if ($validator->fails()) {
                return JsonData::error('参数错误','',500);
            }
            //赋值
            $order_no=$request->order_no;
            $content=$request->text;
            $evaluate1=$request->evaluate1;
            $evaluate2=$request->evaluate2;
//            $evaluate3=$request->evaluate3;

            //查询
            $data=CoOrder::where(["user_id"=>$this->user_info->id,"order_no"=>$order_no])->first();
            if(empty($data)){
                return JsonData::error('订单不存在','',500);
            }
            if($data->status !=4){
                return JsonData::error('订单无法评价','',500);
            }else {
                if($data->is_comments == 1){
                    return JsonData::error('订单已评价','',500);
                }
                $Comment = CoOrderComments::where(["order_no"=>$order_no])->first();
                if(!empty($Comment)){
                    CoOrder::where(["user_id"=>$this->user_info->id,"order_no"=>$order_no])->update(['is_comments'=>1]);
                    return JsonData::error('订单已评价','',500);
                }
                DB::beginTransaction();
                //咨询评论
                $CoCustomerComment = new CoOrderComments();
                $CoCustomerComment->content = $content;
                $CoCustomerComment->user_id = $this->user_info->id;
                $CoCustomerComment->order_no = $order_no;
                $CoCustomerComment->evaluate1 = $evaluate1;
                $CoCustomerComment->evaluate2 = $evaluate2;
                $CoCustomerComment->created_at =  date("Y-m-d h:i:s",time());
                $res = $CoCustomerComment->save();
                if($res){
                    $res = CoOrder::where(["user_id"=>$this->user_info->id,"order_no"=>$order_no])->update(['is_comments'=>1]);
                    if($res){
                        DB::commit();
                        return JsonData::success('评价成功','',200);
                    }
                }
                DB::rollBack();
                return JsonData::error('评价失败','',500);
            }
        } catch (\Exception $e) {
            //配置错误时排除异常
            return JsonData::error( $e->getMessage(),'',500);
        }
    }

}
